#include "shadermanager.h"
#include "shader_impl.h"

namespace ZH
{
	ShaderManager* Singleton<ShaderManager>::ms_Singleton = NULL;

	ShaderManager::ShaderManager()
	{	}

	ShaderManager::~ShaderManager()
	{
		Cleanup();
	}

	ShaderManager& ShaderManager::getSingleton()
	{
		return Singleton<ShaderManager>::getSingleton();
	}

	ShaderManager* ShaderManager::getSingletonPtr()
	{
		return Singleton<ShaderManager>::getSingletonPtr();
	}

	Shader* ShaderManager::CreateVertexShader(LPDIRECT3DDEVICE9 device, const std::string& program, const std::string& function, const std::string& profile)
	{
		Shader* pTarget = GetShader(Shader::emTypeVertex, function);
		if (NULL != pTarget)
			return pTarget;
		
		pTarget = new VertexShader(device, program, function, profile);
		assert(pTarget);
		m_mapVertexShaders[function] = pTarget;
		return pTarget;
	}

	Shader* ShaderManager::CreateFragmentShader(LPDIRECT3DDEVICE9 device, const std::string& program, const std::string& function, const std::string& profile)
	{
		Shader* pTarget = GetShader(Shader::emTypeFragment, function);
		if (NULL != pTarget)
			return pTarget;

		pTarget = new FragmentShader(device, program, function, profile);
		assert(pTarget);
		m_mapFragmentShaders[function] = pTarget;
		return pTarget;
	}
	
	Shader* ShaderManager::GetShader(Shader::ShaderType type, const std::string& function)const
	{
		if (Shader::emTypeVertex == type)
		{
			MAP_SHADER::const_iterator it = m_mapVertexShaders.find(function);
			if (it == m_mapVertexShaders.end())
				return NULL;
			else
				return it->second;
		}

		if (Shader::emTypeFragment == type)
		{
			MAP_SHADER::const_iterator it = m_mapFragmentShaders.find(function);
			if (it == m_mapFragmentShaders.end())
				return NULL;
			else
				return it->second;
		}

		return NULL;
	}

	void ShaderManager::Cleanup()
	{
		MAP_SHADER::iterator end;
		MAP_SHADER::iterator beg;
		for (beg = m_mapVertexShaders.begin(), end = m_mapVertexShaders.end(); beg != end; ++ beg)
			delete beg->second;
		m_mapVertexShaders.clear();

		for (beg = m_mapFragmentShaders.begin(), end = m_mapFragmentShaders.end(); beg != end; ++ beg)
			delete beg->second;
		m_mapFragmentShaders.clear();
	}
}	// end of namespace ZH
